home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1992 by Rush Record
- * Copyright (C) 1993 by Charles Sandmann (sandmann@clio.rice.edu)
- *
- * This file is part of ED.
- *
- * ED is free software; you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation.
- *
- * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with ED
- * (see the file COPYING). If not, write to the Free Software Foundation, 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
- #include "opsys.h"
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
- #include "memory.h"
- #include "ctyp_dec.h"
- #include "rec.h"
- #include "window.h"
- #include "ed_dec.h" /* global data */
- #include "buffer.h"
- #include "buf_dec.h" /* kill buffers */
- #include "cmd_enum.h"
- #include "handy.h" /* for definition of max() */
- #include "keyvals.h" /* for numeric values corresponding to editor commands */
- #include "file.h"
-
- static buf_node charbuf = {1,1,0,0}; /* single-char buffer for insertion of single chars */
- static rec_node charrec = {0,0,1,0};
- static Char character;
- static buf_node multibuf = {1,1,0,0}; /* buffer for insertion of repeated chars */
- static rec_node multirec = {0,0,0,0};
- static buf_node pagebuf = {0,1,0,0}; /* buffer to hold page delimiter string during page moves */
- static Int specify_position = 0; /* flags a user- or bookmark-specified position in file (-innn) */
- static Int specify_byt = 0; /* flags a bookmark-specified byte offset in record */
- static Int dirpos[128]; /* record numbers in directory listings */
- static Char *greptitle[128]; /* titles of grep windows (used when popping back into them) */
- static rec_ptr grepdata[128]; /* contents of grep windows */
-
- extern rec_ptr dir_find();
- #ifndef NO_FTP
- extern Char *host_filename();
- #endif
-
- /******************************************************************************\
- |Routine: dir_depth
- |Callby: edit
- |Purpose: Calculates the depth of a directory on a filesystem.
- |Arguments:
- | dir is the directory specification.
- \******************************************************************************/
- Int dir_depth(dir)
- Char *dir;
- {
- Char *p,c;
- Int curdirpos,ftpsystem;
-
- ftpsystem = ftp_system(dir);
- if(ftpsystem == 'V' || ftpsystem == 'I')
- {
- for(p = dir + 1;(c = *p++);)
- if(c == '[' || c == '<')
- break;
- if(!strncmp(p,"000000]",strlen("000000]")))
- curdirpos = 0;
- else
- {
- for(curdirpos = 1;(c = *p++);)
- if(c == '.')
- curdirpos++;
- else if(c == ']' || c == '>')
- break;
- }
- }
- else
- {
- for(p = dir + 1,curdirpos = 0;(c = *p++);curdirpos += (c == '/')); /* count the '/' characters (past the first one) */
- }
- return(curdirpos);
- }
-
- /******************************************************************************\
- |Routine: position_buffer
- |Callby: edit
- |Purpose: Sets up a buffer to put the cursor at a specified position.
- |Arguments:
- | rec is the line number to start the cursor out on. Line 1 is the first line
- | in the file.
- | byt is the byte offset in that record.
- \******************************************************************************/
- void position_buffer(rec,byt)
- Int rec,byt;
- {
- Int i;
-
- if((CURREC = BASE->next) != BASE) /* if it isn't an empty buffer */
- {
- while(--rec) /* advance in buffer as directed */
- {
- if(CURREC == BASE)
- break;
- CURREC = CURREC->next;
- }
- for(TOPREC = CURREC,i = TOPLIM - TOPROW;i--;TOPREC = TOPREC->prev) /* try to back up to leave margin at top */
- if(TOPREC == BASE->next)
- break;
- for(i = BOTROW - TOPROW,BOTREC = TOPREC;i--;BOTREC = BOTREC->next) /* establish BOTREC */
- if(BOTREC == BASE)
- break;
- while(i-- >= 0) /* deal with being too close to the <eob> */
- {
- if(TOPREC == BASE->next)
- break;
- TOPREC = TOPREC->prev;
- }
- for(BOTREC = TOPREC;BOTREC != CURREC;BOTREC = BOTREC->next,CURROW++);
- BOTREC = TOPREC;
- CURBYT = byt;
- if(CURBYT > CURREC->length)
- CURBYT = CURREC->length;
- CURCOL = get_column(CURREC,CURBYT);
- }
- else /* empty buffer */
- TOPREC = BOTREC = CURREC = BASE;
- }
-
- /******************************************************************************\
- |Routine: edit_init_pos
- |Callby: main parse_fnm
- |Purpose: Sets the initial position in a file.
- |Arguments:
- | pos is the line number to start the cursor out on. Line 1 is the first line in the file.
- \******************************************************************************/
- void edit_init_pos(pos)
- Int pos;
- {
- specify_position = pos;
- }
-
- /******************************************************************************\
- |Routine: edit_init_byt
- |Callby: main
- |Purpose: Sets the byte offset when initial positioning occurs through a
- | bookmark.
- |Arguments:
- | pos is the byte offset to start out with.
- \******************************************************************************/
- void edit_init_byt(pos)
- Int pos;
- {
- specify_byt = pos;
- }
-
- /******************************************************************************\
- |Routine: edit
- |Callby: main
- |Purpose: Implements the user interface.
- |Arguments:
- | fname is the name of the file being edited.
- | multiplefiles is a flag that -m appeared on the command line.
- | comm is the remainder of the command line.
- | commlen is the length of the command buffer.
- \******************************************************************************/
- void edit(fname,multiplefiles,comm,commlen)
- Char *fname; /* the name of the file we're editing */
- Char *multiplefiles; /* flags -m on command line */
- Char *comm; /* buffer containing remainder of command line (examined if -m specified) */
- Int commlen; /* length of command buffer */
- {
- /* this table is a list of flags that tell whether a given key is allowed
- when pressed in a diredit buffer. the 128th entry corresponds to NULL,
- with entries going negative and positive from there.
- */
- static Schar diredit_keymodes[256] =
- {
- /* . a b c d e f g h i j k l m n o p q r s t u v w x y z [ \ ] ^ _ */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,
- 1,1,0,1,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,
- 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* the zero is SPACE */
- 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* the zeroes are A and B */
- 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* the zeroes are a and b */
- };
- static Schar *diredit_keymode = diredit_keymodes + 128;
- static Schar group_keymodes[256] =
- {
- /* . a b c d e f g h i j k l m n o p q r s t u v w x y z [ \ ] ^ _ */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,
- 1,1,0,1,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1, /* the zeroes are R and V */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1, /* the zeroes are r and v */
- };
- static Schar *group_keymode = group_keymodes + 128;
- static Schar article_keymodes[256] =
- {
- /* . a b c d e f g h i j k l m n o p q r s t u v w x y z [ \ ] ^ _ */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,
- 1,1,0,1,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1, /* the zeroes are P, R and V */
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1, /* the zeroes are p, r and v */
- };
- static Schar *article_keymode = article_keymodes + 128;
-
- Int i,j,k,n,deliberate,was_displaying,artnum,read,close,bodycount;
- Int byte,offset,record,searchlength,repeat;
- Int laststatcol,newstatcol,excess,total,bookpos,bookbyt,curdirpos,upmove,binary;
- Char buf[512],editfile[512],recfile[512],bookmark[512],ftpfile[512],artcom[512];
- Char recover,process,*p,bdummy,*filebuf,diredit;
- Schar term,keybuf;
- Uchar *casetable;
- rec_ptr base,rec,rec1,rec2,new,save_rec;
- Char *q;
-
- laststatcol = NCOL;
- charbuf.first = &charrec; /* initialize single char buffer */
- charbuf.last = &charrec;
- charrec.next = (rec_ptr)&charbuf;
- charrec.prev = (rec_ptr)&charbuf;
- charrec.data = &character;
-
- multibuf.first = &multirec; /* initialize repeated-char buffer */
- multibuf.last = &multirec;
- multirec.next = (rec_ptr)&multibuf;
- multirec.prev = (rec_ptr)&multibuf;
-
- pagebuf.first = (rec_ptr)&pagebuf.first; /* initialize page delimiter buffer */
- pagebuf.last = (rec_ptr)&pagebuf.first;
-
- TOPROW = 2; /* set up the screen-oriented context */
- BOTROW = NROW;
- calc_limits(TOPROW,BOTROW,&TOPLIM,&BOTLIM);
- CURROW = 2;
- CURCOL = 1;
- FIRSTCOL = 1;
- WANTCOL = 1;
- NWINDOWS = 0;
- CURWINDOW = new_window(fname); /* this increments NWINDOWS */
- DIRECTION = 1;
- SELREC = 0;
- deliberate = 0; /* no deliberate sideways scrolling in effect */
- memset(dirpos,0,sizeof(dirpos)); /* dirpos[i] = 0 means we haven't visited it yet */
- HEXMODE = (WINDOW[CURWINDOW].binary == 2);
-
- CURBYT = 0; /* initialize the first buffer */
- if(specify_position) /* deal with -i option if present */
- {
- position_buffer(specify_position,specify_byt);
- specify_position = 0; /* it's a one-shot */
- specify_byt = 0;
- }
- else /* position not specified */
- TOPREC = BOTREC = CURREC = BASE->next;
- for(i = 2;i < NROW;i++) /* establish BOTREC */
- {
- if(BOTREC == BASE)
- break;
- BOTREC = BOTREC->next;
- }
- if(i < NROW)
- BOTREC = 0;
-
- ref_display(); /* display the file */
- marge(TOPROW,BOTROW); /* set up scrolling region */
- save_window(); /* load WINDOW[0] in case it's needed */
- /* handle -m on command line */
- if(*multiplefiles)
- {
- while(1)
- {
- save_window();
- if(NWINDOWS >= MAX_WINDOWS)
- break;
- for(total = i = 0;i < NWINDOWS;i++)
- if((excess = WINDOW[i].botrow - WINDOW[i].toprow - 2) > 0) /* there is space available here */
- total += excess;
- if(total < 4)
- break;
- recover = process = 0;
- parse_skip(1); /* flag no prompting in parse_fnm */
- if(!parse_filename(comm,commlen,editfile,&recover,recfile,&process,multiplefiles,&bdummy,&bdummy))
- break;
- base = (rec_ptr)imalloc(sizeof(rec_node));
- base->length = 0;
- base->data = NULL;
- if(load_file(editfile,base,bookmark,&bookpos,&bookbyt,&diredit,binary = WINDOW[CURWINDOW].binary,&filebuf) != -2)
- {
- insert_window(editfile,base,binary,(int)diredit); /* note, this routine may call set_window in order to scroll reduced windows */
- if((i = strlen(bookmark)))
- {
- WINDOW[CURWINDOW].bookmark = (Char *)imalloc(++i);
- strcpy(WINDOW[CURWINDOW].bookmark,bookmark);
- if(--bookpos > 0)
- down_arrow(bookpos);
- if(bookbyt)
- right_arrow(bookbyt);
- }
- WINDOW[CURWINDOW].filebuf = filebuf;
- WINDOW[CURWINDOW].binary = binary;
- WINDOW[CURWINDOW].news = 0;
- }
- }
- }
- while(1) /* main loop */
- {
- if(!deliberate) /* deliberate != 0 means they shifted left or right deliberately */
- {
- if((i = CURCOL - NCOL - FIRSTCOL) > -2)
- {
- FIRSTCOL += i + 10;
- ref_window(CURWINDOW);
- }
- else if(CURCOL < FIRSTCOL)
- {
- FIRSTCOL = max(1,CURCOL - 10);
- ref_window(CURWINDOW);
- }
- }
- else
- deliberate = 0;
- if(REPORTSTATUS && puttest()) /* handle cursor position report if necessary */
- {
- get_position(&record,&byte);
- sprintf(buf,"Rec %d,Byt %d,Col %d",record,CURBYT + 1,CURCOL - FIRSTCOL + 1);
- if(OVERSTRIKE)
- strcat(buf,",Ovr");
- if(BOXCUT)
- strcat(buf,",Box");
- newstatcol = NCOL - strlen(buf) + FIRSTCOL;
- if(laststatcol < newstatcol)
- {
- move(TOPROW - 1,laststatcol);
- ers_end();
- }
- move(TOPROW - 1,laststatcol = newstatcol);
- reverse();
- putz(buf);
- normal();
- }
- if(WINDOW[CURWINDOW].diredit)
- if(CURREC != BASE)
- if(CURCOL < 23)
- {
- CURCOL = 23;
- CURBYT = 22;
- }
- move(CURROW,CURCOL); /* move to where we are */
- repeat = get_next_key(&keybuf);
- unmark_paren(); /* remove parenthesis marking, if any */
- /* verify the keystroke is allowed for a diredit window */
- if((WINDOW[CURWINDOW].diredit && diredit_keymode[keybuf]))
- {
- bell();
- continue;
- }
- /* verify the keystroke is allowed for a group window */
- if(WINDOW[CURWINDOW].news == 1 && group_keymode[keybuf])
- {
- bell();
- continue;
- }
- /* verify the keystroke is allowed for an article window */
- if(WINDOW[CURWINDOW].news == 2 && article_keymode[keybuf])
- {
- bell();
- continue;
- }
- switch(keybuf)
- {
- /*******************************************************************************/
- /* control characters */
- /*******************************************************************************/
-
- /*case KEY_CTRLC:*/ /* control-c, just redisplay */
- /* emulate_key((Schar)KEY_REFRESH,1);
- break;*/
-
- case KEY_BACKSPACE: /* backspace (move to beginning of line, or previous if at beginning) */
- backspace(repeat);
- break;
-
- case KEY_DELPREVWORD: /* delete previous word */
- if(!find_word(-repeat))
- {
- abort_key();
- break;
- }
- if(OVERSTRIKE)
- {
- offset = find_word(-repeat);
- killer(offset,&WORDBUF,0);
- }
- else
- {
- if(repeat > 1)
- {
- offset = find_word(-(repeat - 1));
- killer(offset,0,0);
- WORDBUF.direction = 1;
- }
- offset = find_word(-1);
- killer(offset,&WORDBUF,0);
- }
- WORDBUF.direction = 1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_DEFINEKEY: /* define key */
- define_key();
- break;
-
- case KEY_CARRIAGERETURN: /* carriage return */
- selective:
- #ifndef NO_NEWS
- if(WINDOW[CURWINDOW].news == 1) /* a group selection */
- {
- if(CURREC == BASE)
- bell();
- else
- {
- for(i = 0;i < NWINDOWS;i++) /* find out if an article is displayed */
- if(WINDOW[i].news == 3)
- break;
- if(i < NWINDOWS) /* destroy the article window */
- {
- save_window();
- remove_window(i);
- for(j = 0;j < NMARK;j++) /* adjust marks */
- {
- if(MARKWINDOW[j] == i)
- {
- for(k = j + 1;k < NMARK;k++)
- {
- MARKWINDOW[k - 1] = MARKWINDOW[k];
- MARKREC[k - 1] = MARKREC[k];
- MARKBYT[k - 1] = MARKBYT[k];
- }
- NMARK--;
- j--;
- }
- }
- }
- for(i = 0;i < NWINDOWS;i++)
- if(WINDOW[i].news == 2)
- break;
- newsrc_current(CURREC->data + groupname_offset()); /* figures out which entry in NETRC corresponds to current group, save internal pointer */
- news_group(CURREC->data + groupname_offset(),i,keybuf);
- }
- }
- else if(WINDOW[CURWINDOW].news == 2) /* an article selection */
- {
- if(keybuf == 'P') /* there is no distinction between p and P */
- keybuf = tolower(keybuf);
- if(keybuf == 'p' && !posting_allowed())
- {
- bell();
- slip_message("Posting is not allowed by this news server.");
- wait_message();
- break;
- }
- /* if retrieving an article, don't allow them off the end of the list */
- if(CURREC == BASE && keybuf != 'p')
- bell();
- else
- {
- /* retrieve the article */
- if(CURREC != BASE)
- {
- my_sscanf(CURREC->data,"%d",&artnum); /* get article number */
- sprintf(artcom,"STAT %d",artnum);
- news_command(artcom);
- news_response(buf,sizeof(buf));
- if(buf[0] != '2')
- {
- slip_message("An error occurred while STATing that article:");
- slip_message(buf);
- wait_message();
- break;
- }
- }
- /* generate a new buffer */
- base = (rec_ptr)imalloc(sizeof(rec_node));
- base->length = 0;
- base->data = NULL;
- base->next = base->prev = base;
- /* retrieve the article as appropriate */
- if(keybuf == 'R' || keybuf == 'V')
- news_command("ARTICLE");
- else if(keybuf == 'p')
- {
- if(CURREC == BASE)
- {
- if(!inquire("Subject",buf,sizeof(buf),1))
- {
- toss_data(base);
- break;
- }
- load_post(base,buf);
- }
- else
- {
- p = CURREC->data + 42;
- while(*p == '=')
- p++;
- load_post(base,p);
- news_command(artcom);
- news_response(buf,sizeof(buf));
- if(buf[0] != '2')
- {
- toss_data(base);
- slip_message("An error occurred while STATing that article:");
- slip_message(buf);
- wait_message();
- break;
- }
- news_command("BODY");
- }
- }
- else
- news_command("BODY");
- if(CURREC != BASE)
- {
- news_response(buf,sizeof(buf));
- if(buf[0] != '2')
- {
- slip_message("An error occurred while retrieving that article:");
- slip_message(buf);
- wait_message();
- toss_data(base);
- break;
- }
- }
- if(keybuf != 'p') /* posting doesn't change article-read state */
- {
- read = CURREC->recflags & 2; /* save current state of this entry */
- CURREC->recflags ^= 2; /* toggle its state */
- paint(CURROW,CURROW,FIRSTCOL);
- if(read) /* was already marked read, mark it unread */
- newsrc_mark_unread(artnum);
- else /* was not marked as read, mark it read */
- newsrc_mark_read(artnum);
- }
- /* read the article body */
- if(CURREC != BASE)
- while(1)
- {
- news_response(buf,sizeof(buf));
- if((i = strlen(buf)) == 1 && buf[0] == '.')
- break;
- new = (rec_ptr)imalloc(sizeof(rec_node));
- insq(new,base->prev);
- /* if posting buffer, precede each line with "> " */
- if(keybuf == 'p')
- {
- new->data = (Char *)imalloc(i + 3);
- strcpy(new->data,"> ");
- strcat(new->data,buf);
- new->length = i + 2;
- }
- else
- {
- new->data = (Char *)imalloc(i + 1);
- strcpy(new->data,buf);
- new->length = i;
- }
- new->recflags = 1; /* this is a freeable buffer */
- }
- if(keybuf == 'p')
- {
- new = (rec_ptr)imalloc(sizeof(rec_node));
- new->data = (Char *)imalloc(1);
- *new->data = '\0';
- new->length = 0;
- new->recflags = 1;
- insq(new,base->prev);
- if(CURREC == BASE)
- strcpy(artcom,"New Posting");
- else
- sprintf(artcom,"Followup to article %d",artnum);
- }
- else
- {
- down_arrow(1);
- sprintf(artcom,"Article %d",artnum);
- }
- /* if no news=3 buffer exists, create one */
- for(n = 0;n < NWINDOWS;n++)
- if(WINDOW[n].news == 3)
- break;
- if(n == NWINDOWS)
- {
- save_window();
- insert_window_percent(80);
- insert_window(artcom,base,0,0);
- WINDOW[CURWINDOW].filebuf = NULL;
- WINDOW[CURWINDOW].binary = 0;
- WINDOW[CURWINDOW].diredit = 0;
- WINDOW[CURWINDOW].news = 3;
- if(keybuf == 'p')
- WINDOW[CURWINDOW].news = 4;
- else if(keybuf == 'r' || keybuf == 'R')
- set_window(1); /* move back to the article list window */
- }
- else /* the article window already appears */
- {
- if(WINDOW[n].filename)
- ifree(WINDOW[n].filename);
- WINDOW[n].filename = (Char *)imalloc(strlen(artcom) + 1);
- strcpy(WINDOW[n].filename,artcom);
- toss_data(WINDOW[n].base);
- WINDOW[n].base = base;
- WINDOW[n].currec = WINDOW[n].toprec = base->next;
- new_botrec(n);
- WINDOW[n].curbyt = 0;
- WINDOW[n].currow = WINDOW[n].toprow;
- WINDOW[n].curcol = WINDOW[n].firstcol = WINDOW[n].wantcol = 1;
- WINDOW[n].modified = WINDOW[n].diredit = WINDOW[n].binary = 0;
- WINDOW[n].news = 3;
- ref_window(n);
- if(keybuf == 'v' || keybuf == 'V')
- set_window(n);
- if(keybuf == 'p')
- WINDOW[n].news = 4;
- save_window();
- }
- }
- }
- else
- #endif
- if(WINDOW[CURWINDOW].diredit)
- {
- if(CURREC == BASE)
- {
- abort_key();
- bell();
- break;
- }
- else
- {
- unselect();
- curdirpos = dir_depth(WINDOW[CURWINDOW].filename);
- /* generate the complete selected file name */
- strcpy(buf,WINDOW[CURWINDOW].filename);
- if((p = strstr(buf," - GREP window")))
- *p = '\0';
- else if((p = strstr(buf," - PERG window")))
- *p = '\0';
- strcat(buf,CURREC->data + filename_offset());
- /* handle symbolic link format for ftp diredits */
- if((p = strstr(buf," -> ")))
- *p = '\0';
- /* store the position in the current listing, unless they're going up */
- if(strcmp(CURREC->data + filename_offset(),"[-]") && strcmp(CURREC->data + filename_offset(),".."))
- {
- get_position(&record,&byte);
- dirpos[curdirpos] = record;
- upmove = 0;
- }
- else
- upmove = 1;
- /* parse VMS-y dirnames */
- if(!ftp_unixy(ftp_system(buf)))
- {
- while((p = strstr(buf,"][")))
- for(q = p + 2;(*p++ = *q++););
- if((p = strstr(buf,"-]")))
- {
- while(*--p != '.')
- if(*p == '[')
- break;
- if(*p == '[')
- strcpy(++p,"000000]");
- else
- strcpy(p,"]");
- }
- /* this code used to turn [000000.X] to [X]. some servers are picky.
- if((p = strstr(buf,"[000000.")))
- {
- p++;
- for(q = p + 7;(*p++ = *q++););
- }*/
- }
- /* if they selected a directory */
- if(CURREC->data[0] == 'd' || CURREC->data[0] == 'l')
- {
- if(ftp_unixy(ftp_system(buf)))
- strcat(buf,"/");
- #ifndef NO_FTP
- if((i = host_in_name(buf))) /* this is true if /xxx.yyy.zzz: is in the file name */
- {
- p = host_filename(i,buf,ftpfile); /* this does all the parsing */
- if((base = dir_find(CURWINDOW,ftpfile))) /* check whether we've visited here yet */
- {
- strcpy(fname,ftpfile);
- goto dispwin;
- }
- }
- #endif
- /* create new buffer */
- base = (rec_ptr)imalloc(sizeof(rec_node));
- base->length = 0;
- base->data = NULL;
- base->prev = base->next = base;
- /* check for return to a GREP window */
- curdirpos = dir_depth(fname);
- if(upmove && grepdata[curdirpos - 1])
- {
- copy_records(grepdata[curdirpos - 1],base,0,0);
- strcpy(fname,greptitle[curdirpos - 1]);
- goto dispwin;
- }
- /* read in the directory */
- if(read_in_diredit(fname,buf,base) > 0)
- {
- dispwin:
- if(host_in_name(ftpfile))
- dir_store(CURWINDOW,ftpfile,base);
- else
- toss_data(BASE);
- BASE = base;
- CURROW = TOPROW;
- CURCOL = 1;
- FIRSTCOL = 1;
- WANTCOL = 1;
- DIRECTION = 1;
- SELREC = 0;
- TOPREC = BOTREC = CURREC = BASE->next;
- /* do magical parsing ad nauseam */
- if(upmove)
- {
- curdirpos = dir_depth(fname);
- if(dirpos[curdirpos])
- position_buffer(dirpos[curdirpos],0);
- else /* we haven't been here yet, find olddir in the list */
- {
- strcpy(buf,WINDOW[CURWINDOW].filename);
- if(ftp_unixy(ftp_system(buf)))
- {
- buf[strlen(buf) - 1] = '\0'; /* strip the final '/' */
- if(strlen(buf))
- {
- p = strrchr(buf,'/') + 1; /* point to dirname */
- for(i = 1,rec = BASE->next;rec != BASE;rec = rec->next,i++)
- if(!strcmp(rec->data + filename_offset(),p))
- break;
- position_buffer(i,0);
- }
- else
- position_buffer(1,0);
- }
- else
- {
- for(p = buf + strlen(buf);p != buf;)
- {
- if(*--p == ':')
- break;
- if(*p == '[')
- break;
- if(*p == '.')
- break;
- }
- if(*p == ':')
- position_buffer((dirpos[curdirpos] = 1),0);
- else
- {
- if(*p == '.')
- *--p = '[';
- else
- {
- *p-- = '.';
- *p = '[';
- }
- for(i = 1,rec = BASE->next;rec != BASE;rec = rec->next,i++)
- if(!inscmp(rec->data + filename_offset(),p))
- break;
- position_buffer(i,0);
- }
- }
- }
- }
- for(i = TOPROW;i < BOTROW;i++) /* establish BOTREC */
- {
- if(BOTREC == BASE)
- break;
- BOTREC = BOTREC->next;
- }
- if(i < BOTROW)
- BOTREC = 0;
- ifree(WINDOW[CURWINDOW].filename);
- WINDOW[CURWINDOW].filename = (Char *)imalloc(strlen(fname) + 1); /* this line cannot be merged with the following one... */
- strcpy(WINDOW[CURWINDOW].filename,fname); /* ...without generating a pointer mismatch error under VMS cc */
- WINDOW[CURWINDOW].base = BASE;
- save_window();
- ref_window(CURWINDOW);
- }
- else /* read_in_diredit failed, if it's a link, try doing it more directly */
- {
- if(CURREC->data[0] == 'l')
- goto open_window;
- ifree(base);
- bell();
- }
- break;
- }
- open_window:
- wincom_special();
- emulate_key((Schar)KEY_WINDOW,1);
- emulate_key((Schar)'o',1);
- emulate_key((Schar)KEY_CARRIAGERETURN,1);
- strcpy(buf,WINDOW[CURWINDOW].filename);
- if((p = strstr(buf," - GREP window")))
- *p = '\0';
- else if((p = strstr(buf," - PERG window")))
- *p = '\0';
- for(i = strlen((p = buf));i--;emulate_key((Schar)*p++,1));
- strcpy(buf,CURREC->data + filename_offset());
- /* set grepdata to NULL, tossing anything that was there (a quasi-memory-leak) */
- curdirpos = dir_depth(buf);
- if(grepdata[curdirpos])
- {
- toss_data(grepdata[curdirpos]);
- grepdata[curdirpos] = NULL;
- }
- if(greptitle[curdirpos])
- {
- ifree(greptitle[curdirpos]);
- greptitle[curdirpos] = NULL;
- }
- /* handle symbolic link format for ftp diredits */
- if((p = strstr(buf," -> ")))
- *p = '\0';
- for(i = 0;i < strlen(buf);i++)
- emulate_key((Schar)buf[i],1);
- emulate_key((Schar)KEY_CARRIAGERETURN,1);
- if(host_in_name(WINDOW[CURWINDOW].filename))
- ftp_fileonly();
- }
- }
- else
- {
- carriage_return(repeat);
- WINDOW[CURWINDOW].modified = 1;
- }
- break;
-
- case KEY_DELTOBEGLINE: /* delete to beginning of line */
- emulate_key((Schar)KEY_DELTOBEGLINE2,repeat);
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_REFRESH: /* refresh screen */
- ref_display();
- break;
-
- case KEY_DELTOBEGLINE2: /* delete to beginning of line */
- if(!find_line(-repeat))
- {
- abort_key();
- break;
- }
- if(OVERSTRIKE)
- {
- offset = find_line(-repeat);
- killer(offset,&LINEBUF,0);
- }
- else
- {
- if(repeat > 1)
- {
- offset = find_line(-(repeat - 1));
- killer(offset,0,0);
- LINEBUF.direction = 1;
- }
- offset = find_line(-1);
- killer(offset,&LINEBUF,0);
- }
- LINEBUF.direction = 1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- /*case KEY_CTRLY:*/ /* control-y */
- /* emulate_key((Schar)KEY_REFRESH,repeat);
- break;*/
-
- case KEY_COMMAND: /* command */
- emulate_key((Schar)KEY_COMMAND2,repeat);
- break;
-
- case KEY_DELETE: /* delete */
- if(!find_char(-repeat))
- {
- abort_key();
- break;
- }
- if(OVERSTRIKE)
- killer(-repeat,&CHARBUF,0);
- else
- {
- if(repeat > 1)
- killer(1L - repeat,0,0);
- killer(-1L,&CHARBUF,0);
- }
- CHARBUF.direction = 1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- /*******************************************************************************/
- /* keypad keys */
- /*******************************************************************************/
-
- case KEY_UPARROW: /* up arrow */
- copy_only(0);
- up_arrow(repeat);
- break;
-
- case KEY_DOWNARROW: /* down arrow */
- copy_only(0);
- down_arrow(repeat);
- break;
-
- case KEY_RIGHTARROW: /* right arrow */
- copy_only(0);
- right_arrow(repeat);
- break;
-
- case KEY_LEFTARROW: /* left arrow */
- copy_only(0);
- left_arrow(repeat);
- break;
-
- case KEY_MOVEBYLINE: /* move by line */
- if(WINDOW[CURWINDOW].diredit && DIRECTION == -1)
- emulate_key((Schar)KEY_UPARROW,repeat);
- else
- {
- copy_only(0);
- move_line(repeat);
- }
- break;
-
- case KEY_MOVEBYWORD: /* move by word */
- copy_only(0);
- move_word(repeat);
- break;
-
- case KEY_MOVEBYEOL: /* move to end of line */
- copy_only(0);
- move_eol(repeat);
- break;
-
- case KEY_MOVEBYCHAR: /* move by character */
- copy_only(0);
- if(DIRECTION == 1)
- right_arrow(repeat);
- else
- left_arrow(repeat);
- break;
-
- case KEY_FORWARD: /* set forward */
- copy_only(0);
- DIRECTION = 1;
- break;
-
- case KEY_BACKWARD: /* set backward */
- copy_only(0);
- DIRECTION = -1;
- break;
-
- case KEY_KILL: /* kill */
- match_init(SEARCH_FLAGS);
- if(SELREC != 0)
- {
- offset = get_offset(SELREC,SELBYT,get_seldir());
- if(WINDOW[CURWINDOW].diredit || WINDOW[CURWINDOW].news == 1 || WINDOW[CURWINDOW].news == 2)
- {
- if(offset < 0 && SELREC != CURREC)
- {
- rec1 = SELREC;
- rec2 = CURREC->prev;
- }
- else if(offset > 0 && SELREC != CURREC)
- {
- rec1 = CURREC;
- rec2 = SELREC->prev;
- }
- else
- break;
- while(1)
- {
- #ifndef NO_NEWS
- if(WINDOW[CURWINDOW].news == 2) /* handle newsrc dbs if it's an article window */
- {
- my_sscanf(rec1->data,"%d",&artnum);
- if(rec1->recflags & 2) /* the article is marked read */
- newsrc_mark_unread(artnum);
- else
- newsrc_mark_read(artnum);
- }
- #endif
- rec1->recflags ^= 2;
- if(rec1 == rec2)
- break;
- rec1 = rec1->next;
- }
- unselect();
- ref_window(CURWINDOW);
- }
- else
- {
- unselect();
- if(BOXCUT)
- {
- if(WINDOW[CURWINDOW].binary)
- {
- slip_message("You can't use box mode in binary buffers.");
- wait_message();
- abort_key();
- break;
- }
- else
- killer_box();
- }
- killer(offset,&KILLBUF,0);
- if(offset < 0)
- KILLBUF.direction = 1;
- else
- KILLBUF.direction = -1;
- }
- }
- else if((offset = match_search(CURREC,CURBYT,&SEARCHBUF)) != 0)
- {
- killer(offset,&KILLBUF,0);
- KILLBUF.direction = 1;
- }
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_MOVEBYPAGE: /* move by page */
- copy_only(0);
- if(!PAGE_BREAK_LENGTH)
- break;
- load_buffer(&pagebuf,PAGE_BREAK,PAGE_BREAK_LENGTH);
- match_init("ebnnn");
- if(DIRECTION < 0 && !match_search(CURREC,CURBYT,&pagebuf))
- repeat++;
- offset = find_string(CURREC,CURBYT,DIRECTION,&pagebuf,"ebnnn",repeat);
- if(DIRECTION == 1)
- {
- if(offset != 0)
- right_arrow(offset);
- else
- {
- abort_key();
- emulate_key((Schar)KEY_ENDOFFILE,1); /* treat as move-to-end-of-file */
- }
- }
- else
- {
- if(offset != 0)
- left_arrow(-offset);
- else
- {
- abort_key();
- emulate_key((Schar)KEY_TOPOFFILE,1); /* treat as move-to-top-of-file */
- }
- }
- if(offset != 0 && CURROW <= BOTLIM)
- {
- down_arrow(BOTLIM - TOPROW);
- up_arrow(BOTLIM - TOPLIM);
- }
- break;
-
- case KEY_MOVEBYSECTION: /* move by section */
- copy_only(0);
- if(SECTION_LINES <= 0)
- {
- if((i = repeat * ((BOTROW - TOPROW) + SECTION_LINES)) < 1)
- i = 1;
- }
- else
- i = repeat * SECTION_LINES;
- if(DIRECTION == 1)
- down_arrow(i);
- else
- up_arrow(i);
- break;
-
- case KEY_APPEND: /* append */
- match_init(SEARCH_FLAGS);
- if(SELREC != 0)
- {
- offset = get_offset(SELREC,SELBYT,get_seldir());
- unselect();
- if(BOXCUT)
- killer_box();
- killer(offset,&KILLBUF,1);
- }
- else if((offset = match_search(CURREC,CURBYT,&SEARCHBUF)) != 0)
- killer(offset,&KILLBUF,1);
- KILLBUF.direction = 1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_DELWORD: /* delete word */
- if(!find_word(repeat))
- {
- abort_key();
- copy_only(0);
- break;
- }
- if(OVERSTRIKE)
- {
- offset = find_word(repeat);
- killer(offset,&WORDBUF,0);
- }
- else
- {
- if(repeat > 1)
- {
- offset = find_word(repeat - 1);
- killer(offset,0,0);
- }
- offset = find_word(1);
- killer(offset,&WORDBUF,0);
- }
- WORDBUF.direction = -1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_DELCHAR: /* delete character */
- if(!find_char(repeat))
- {
- abort_key();
- copy_only(0);
- break;
- }
- if(OVERSTRIKE)
- killer(repeat,&CHARBUF,0);
- else
- {
- if(repeat > 1)
- killer(repeat - 1L,0,0);
- killer(1L,&CHARBUF,0);
- }
- CHARBUF.direction = -1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_SELECT: /* select */
- copy_only(0);
- unselect(); /* remove selection if it is already active */
- SELREC = CURREC;
- SELBYT = CURBYT;
- SELDIR = 0;
- move(CURROW,CURCOL);
- doselect(CURREC,CURBYT);
- move(CURROW,CURCOL);
- break;
-
- case KEY_ENTER: /* enter */
- copy_only(0);
- break;
-
- case KEY_GOLD: /* gold */
- copy_only(0);
- reverse();
- putz("That was interesting.");
- normal();
- break;
-
- case KEY_SETCOPY: /* set copy select */
- copy_only(1);
- break;
-
- case KEY_FINDNEXT: /* find next */
- copy_only(0);
- if(WINDOW[CURWINDOW].diredit && DIRECTION == -1)
- {
- i = CURBYT;
- CURBYT = 0;
- }
- if((offset = find_string(CURREC,CURBYT,DIRECTION,&SEARCHBUF,SEARCH_FLAGS,repeat)) != 0)
- {
- if(DIRECTION == 1)
- right_arrow(offset);
- else
- left_arrow(-offset);
- }
- else
- {
- if(WINDOW[CURWINDOW].diredit && DIRECTION == -1)
- CURBYT = i;
- abort_key();
- bell();
- }
- break;
-
- case KEY_DELLINE: /* delete line */
- if(WINDOW[CURWINDOW].diredit || WINDOW[CURWINDOW].news == 1 || WINDOW[CURWINDOW].news == 2)
- {
- #ifndef NO_NEWS
- if(WINDOW[CURWINDOW].news == 2)
- {
- my_sscanf(CURREC->data,"%d",&artnum);
- if(CURREC->recflags & 2) /* the article is marked read */
- newsrc_mark_unread(artnum);
- else
- newsrc_mark_read(artnum);
- }
- #endif
- CURREC->recflags ^= 2;
- paint(CURROW,CURROW,FIRSTCOL);
- }
- else
- {
- if(!find_line(repeat))
- {
- abort_key();
- copy_only(0);
- break;
- }
- if(OVERSTRIKE)
- {
- offset = find_line(repeat);
- killer(offset,&LINEBUF,0);
- }
- else
- {
- if(repeat > 1)
- {
- offset = find_line(repeat - 1);
- killer(offset,0,0);
- }
- offset = find_line(1);
- killer(offset,&LINEBUF,0);
- }
- LINEBUF.direction = -1;
- WINDOW[CURWINDOW].modified = 1;
- }
- break;
-
- case KEY_OPENLINE: /* open line */
- copy_only(0);
- openline(repeat);
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_CHANGECASE: /* change case */
- switch(CASECHANGE)
- {
- case CASE_UPPER:
- casetable = _my_toupper_;
- break;
- case CASE_LOWER:
- casetable = _my_tolower_;
- break;
- case CASE_OPPOSITE:
- casetable = _my_tooppos_;
- break;
- case CASE_CAPITALIZE:
- casetable = NULL;
- break;
- }
- copy_only(0);
- match_init(SEARCH_FLAGS);
- if(SELREC != 0)
- {
- offset = get_offset(SELREC,SELBYT,get_seldir());
- unselect();
- change_case(offset,0,casetable);
- }
- else if((offset = match_search(CURREC,CURBYT,&SEARCHBUF)) != 0)
- change_case(offset,(SEARCH_FLAGS[((int)SMODE_EXACT) >> 1] == 'e')? 0 : 1,casetable);
- else
- if(!change_case(repeat * DIRECTION,1,casetable))
- abort_key();
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_DELTOEOL: /* delete to end of line */
- if(!find_line(repeat))
- {
- abort_key();
- copy_only(0);
- break;
- }
- if(OVERSTRIKE)
- {
- offset = find_line(repeat) - 1;
- killer(offset,&LINEBUF,0);
- }
- else
- {
- if(repeat > 1)
- {
- offset = find_line(repeat - 1) - 1;
- killer(offset,0,0);
- }
- offset = find_line(1) - 1;
- killer(offset,&LINEBUF,0);
- }
- LINEBUF.direction = -1;
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_SPECIALINSERT: /* special insert */
- copy_only(0);
- keybuf = (repeat < 128)? repeat : (repeat - 256);
- repeat = 1;
- goto insert_char;
-
- case KEY_ENDOFFILE: /* bottom of file */
- copy_only(0);
- forgive();
- down_arrow(0x7fffffff);
- begrudge();
- WANTCOL = 0;
- break;
-
- case KEY_TOPOFFILE: /* top of file */
- copy_only(0);
- forgive();
- up_arrow(0x7fffffff);
- left_arrow(0x7fffffff);
- begrudge();
- WANTCOL = 0;
- break;
-
- case KEY_UNKILL: /* unkill */
- copy_only(0);
- for(i = 0;i < repeat;i++)
- {
- if(BOXCUT)
- insert_box();
- insert(&KILLBUF);
- }
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_COMMAND2: /* command */
- copy_only(0);
- if((i = command(grepdata,greptitle)))
- {
- if(i == 1) /* normal EXIT, QUIT etc. */
- {
- for(i = 0;i < sizeof(grepdata) / sizeof(rec_ptr);i++)
- {
- if(grepdata[i])
- {
- toss_data(grepdata[i]);
- grepdata[i] = NULL;
- }
- if(greptitle[i])
- {
- ifree(greptitle[i]);
- greptitle[i] = NULL;
- }
- }
- return;
- }
- #ifndef NO_NEWS
- /* find the posting window */
- for(close = 0;close < NWINDOWS;close++)
- if(WINDOW[close].news == 4)
- break;
- /* insert the Lines header */
- rescan:
- if(WINDOW[close].base->next == WINDOW[close].base)
- {
- bad_posting:
- slip_message("That posting doesn't seem to contain anything, ignoring it.");
- wait_message();
- goto clean_posting;
- }
- if(i == -2)
- {
- slip_message("Posting aborted.");
- wait_message();
- goto clean_posting;
- }
- for(j = k = 0,rec = WINDOW[close].base->next;rec != WINDOW[close].base;rec = rec->next,j++)
- if(!k && !rec->length) /* found a blank line */
- if(!j) /* it is at top of file, remove it and try again */
- {
- ifree(rec->data);
- remq(rec);
- ifree(rec);
- goto rescan;
- }
- else
- {
- save_rec = rec; /* save blank line position, Lines: will go preceeding it */
- k = j;
- }
- if(!(bodycount = j - k - 1)) /* total lines in body. if zero, find the Reply-To: line and insert count following that */
- {
- for(j = k = 0,rec = WINDOW[close].base->next;rec != WINDOW[close].base;rec = rec->next,j++)
- if(!k && !strncmp(rec->data,"Reply-To: ",strlen("Reply-To: ")))
- {
- save_rec = rec;
- k = j;
- break;
- }
- if(!(bodycount = j - k - 1))
- goto bad_posting;
- new = (rec_ptr)imalloc(sizeof(rec_node));
- *(new->data = (Char *)imalloc(1)) = '\0';
- new->length = 0;
- new->recflags = 1;
- insq(new,save_rec); /* insert a blank record following Reply-To: */
- save_rec = save_rec->next;
- }
- /* insert the Lines: header */
- new = (rec_ptr)imalloc(sizeof(rec_node));
- sprintf(buf,"Lines: %d",bodycount);
- new->data = (Char *)imalloc((new->length = strlen(buf)) + 1);
- strcpy(new->data,buf);
- new->recflags = 1;
- insq(new,save_rec->prev);
- /* post the article */
- news_command("POST");
- news_response(buf,sizeof(buf));
- if(strncmp(buf,"340 ",4))
- {
- bell();
- slip_message(buf + 4);
- wait_message();
- goto clean_posting;
- }
- for(rec = WINDOW[close].base->next;rec != WINDOW[close].base;rec = rec->next)
- news_command(rec->data);
- news_command(".");
- news_response(buf,sizeof(buf));
- slip_message(buf + 4);
- wait_message();
- clean_posting:
- remove_window(close);
- for(i = 0;i < NMARK;i++)
- {
- if(MARKWINDOW[i] == close)
- {
- for(j = i + 1;j < NMARK;j++)
- {
- MARKWINDOW[j - 1] = MARKWINDOW[j];
- MARKREC[j - 1] = MARKREC[j];
- MARKBYT[j - 1] = MARKBYT[j];
- }
- NMARK--;
- i--;
- }
- }
- #endif /* NO_NEWS */
- }
- break;
-
- case KEY_FILL: /* fill */
- copy_only(0);
- if(!SELREC)
- {
- abort_key();
- break;
- }
- word_fill();
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_REPLACE: /* replace */
- copy_only(0);
- match_init(SEARCH_FLAGS);
- if((offset = match_search(CURREC,CURBYT,&SEARCHBUF)) != 0)
- {
- killer(offset,&pagebuf,0);
- insert(&KILLBUF);
- WINDOW[CURWINDOW].modified = 1;
- }
- else
- abort_key();
- break;
-
- case KEY_UNDELWORD: /* undelete word */
- copy_only(0);
- for(i = 0;i < repeat;i++)
- insert(&WORDBUF);
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_UNDELCHAR: /* undelete character */
- copy_only(0);
- for(i = 0;i < repeat;i++)
- insert(&CHARBUF);
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_UNSELECT: /* unselect */
- copy_only(0);
- unselect();
- break;
-
- case KEY_SUBSTITUTE: /* substitute */
- copy_only(0);
- match_init(SEARCH_FLAGS);
- if((searchlength = match_search(CURREC,CURBYT,&SEARCHBUF)) != 0)
- {
- KILLBUF.direction = DIRECTION;
- if(repeat > 1)
- {
- was_displaying = puttest();
- putoff();
- }
- else
- toggle_paren();
- for(i = 0;i < repeat;i++)
- {
- killer(searchlength,&pagebuf,0);
- WINDOW[CURWINDOW].modified = 1;
- if(KILLBUF.nrecs > 0)
- insert(&KILLBUF);
- if(DIRECTION == 1)
- left_arrow(1); /* otherwise, we might already be sitting on the next string to replace */
- if((offset = find_string(CURREC,CURBYT,DIRECTION,&SEARCHBUF,SEARCH_FLAGS,1)) != 0)
- {
- if(DIRECTION == 1)
- right_arrow(offset);
- else
- left_arrow(-offset);
- }
- else
- {
- bell();
- emulate_abort();
- abort_key();
- break;
- }
- }
- KILLBUF.direction = 1;
- if(repeat <= 1) /* CWS 11-93 non-display toggle bug */
- toggle_paren();
- else if(was_displaying)
- {
- puton();
- ref_display();
- move(CURROW,CURCOL);
- }
- }
- else
- abort_key();
- break;
-
- case KEY_GOLDGOLD: /* gold-gold */
- copy_only(0);
- break;
-
- case KEY_WINDOW: /* window */
- copy_only(0);
- wincom();
- break;
-
- case KEY_FIND: /* find */
- copy_only(0);
- i = inquire("Search for",buf,sizeof(buf),0);
- paint(BOTROW,BOTROW,FIRSTCOL);
- if(!i)
- break;
- term = get_terminator();
- if(term == KEY_FORWARD)
- DIRECTION = 1;
- else if(term == KEY_BACKWARD)
- DIRECTION = -1;
- load_buffer(&SEARCHBUF,buf,i);
- if(SEARCH_FLAGS[((int)SMODE_CHAR) >> 1] == 'w' && SEARCHBUF.nrecs > 1)
- {
- buffer_empty(&SEARCHBUF);
- slip_message("Embedded <cr>s don't work when SET SEARCH WORD is in effect.");
- wait_message();
- break;
- }
- if((offset = find_string(CURREC,CURBYT,DIRECTION,&SEARCHBUF,SEARCH_FLAGS,repeat)) != 0)
- {
- if(DIRECTION == 1)
- right_arrow(offset);
- else
- left_arrow(-offset);
- }
- else
- {
- emulate_abort();
- abort_key();
- bell();
- }
- break;
-
- case KEY_UNDELLINE: /* undelete line */
- copy_only(0);
- for(i = 0;i < repeat;i++)
- insert(&LINEBUF);
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- case KEY_RETURN: /* gold up (return to spot) */
- copy_only(0);
- for(i = NMARK - 1;i >= 0;i--)
- if(MARKWINDOW[i] != CURWINDOW || MARKREC[i] != CURREC || MARKBYT[i] != CURBYT)
- {
- save_window();
- set_window(MARKWINDOW[i]);
- offset = get_offset(MARKREC[i],MARKBYT[i],get_markdir(MARKREC[i],MARKBYT[i]));
- if(offset < 0)
- left_arrow(-offset);
- else if(j > 0)
- right_arrow(offset);
- break;
- }
- break;
-
- case KEY_MARK: /* gold down (mark spot) */
- copy_only(0);
- for(i = 0;i < NMARK;i++)
- if(MARKWINDOW[i] == CURWINDOW && MARKREC[i] == CURREC && MARKBYT[i] == CURBYT)
- {
- for(j = i + 1;j < NMARK;j++)
- {
- MARKWINDOW[j - 1] = MARKWINDOW[j];
- MARKREC[j - 1] = MARKREC[j];
- MARKBYT[j - 1] = MARKBYT[j];
- }
- NMARK--;
- goto label41;
- }
- if(NMARK == MAX_MARKS) /* mark a new spot */
- break;
- MARKWINDOW[NMARK] = CURWINDOW;
- MARKREC[NMARK] = CURREC;
- MARKBYT[NMARK++] = CURBYT;
- label41:
- break;
-
- case KEY_SCROLLRIGHT: /* gold right (scroll right) */
- copy_only(0);
- if(FIRSTCOL > 1)
- {
- FIRSTCOL = max(1,FIRSTCOL - NCOL / 4);
- ref_window(CURWINDOW);
- }
- deliberate = 1;
- break;
-
- case KEY_SCROLLLEFT: /* gold left (scroll left) */
- copy_only(0);
- FIRSTCOL += NCOL / 4;
- ref_window(CURWINDOW);
- deliberate = 1;
- break;
-
- default:
- insert_char: /* user inserts a character */
- if(WINDOW[CURWINDOW].news == 1 || WINDOW[CURWINDOW].news == 2)
- goto selective;
- if(WINDOW[CURWINDOW].diredit)
- {
- if(CURREC->data[0] == 'd')
- goto selective;
- switch(keybuf)
- {
- case 'A':
- case 'a':
- case ' ':
- goto selective;
- case 'B':
- case 'b':
- force_binary();
- goto selective;
- }
- }
- copy_only(0);
- if(AUTOWRAP && (keybuf != ' ') && (CURCOL > WRAP_MARGIN)) /* handle autowrap */
- if(autowrp(keybuf)) /* returns 1 if autowrapping was possible (and was done) */
- continue;
- if(repeat == 1)
- {
- if((character = keybuf) == '}' && CFRIENDLY)
- cfrendly(&charbuf,&multibuf,&multirec); /* deal with closure of C-block */
- else
- insert(&charbuf); /* just insert character */
- }
- else /* multiple-character insertion */
- {
- multirec.data = (Char *)imalloc(repeat + 1);
- memset(multirec.data,(Char)keybuf,repeat);
- multirec.length = repeat;
- insert(&multibuf);
- ifree(multirec.data);
- }
- WINDOW[CURWINDOW].modified = 1;
- break;
-
- /*******************************************************************************/
- } /* end of switch */
- } /* end of forever loop */
- }
-
-